import { ecs } from "db://oops-framework/libs/ecs/ECS";
import { SkillModelComp } from "./model/SkillModelComp";
import { Role } from "../../role/Role";
import { BattleDamageType, BattleTriggerEvent } from "../scene/model/BattleEnum";
import { ISkillReport } from "./model/report/ISkillReport";
import { RoleModuleType } from "../../role/model/RoleEnum";
import { EffectDamage } from "./model/report/EffectDamage";
import { Label, v3 } from "cc";
import { EffectSingleCase } from "db://oops-framework/libs/animator-effect/EffectSingleCase";
import { RoleViewComp } from "../../role/view/RoleViewComp";
import { ViewUtil } from "db://oops-framework/core/utils/ViewUtil";
import { SpineFinishedRelease } from "db://oops-framework/libs/animator-effect/2d/SpineFinishedRelease";
import { EffectRecovery } from "../scene/model/EffectRecovery";

/** 
 * 技能系统
 * 1、主动触发：在技能释放条件满足时选择释放
 * 2、被动触发：
 *    - 战斗中在满足技能释放条件时自动触发
 *    - 全场景永久增加数值
 * 3、技能释放流程事件系统
 * 
 * 注意问题：
 * 1、近战攻击中反伤受击打断攻击后摇，战报需要插入到本次技能发起者战报队列中
 * 2、一个技能中有多个不同条件下触发的不同技能效果
 * 
 * 技能流程
 * 1、起手->目标受击前->目标受击后->目标死亡前->目标死亡后（所有细节数据在战报中记录，可做为条件设计技能）
 */
@ecs.register(`Skill`)
export class Skill extends ecs.Entity {
    // 数据层
    SkillModel!: SkillModelComp;

    //逻辑层

    protected init() {
        this.addComponents<ecs.Comp>(
            SkillModelComp);
    }
    /**
    * 技能施放数值计算
    * @param role   当前释放技能的角色
    * @param target 指定目标角色
    */
    cast(caster: Role = null!, target: Role = null!, event: BattleTriggerEvent = BattleTriggerEvent.Casting) {
        if (!this.SkillModel.learned) {
            return
        }
        var casting = this.SkillModel.casting;
        casting.skill = this;
        casting.caster = caster;
        casting.target = target;

        // 释放技能，施放条件在重写方法中自定义
        (casting as any)[event]();
    }
      /**
     * 当敌方被添加buff时 技能施放数值计算
     * @param caster 当前释放技能的角色
     * @param target 指定目标角色
     * @param event  触发事件名
     * @param buff   被添加的buff
     * @returns 
     */
      cast1(caster: Role = null!, target: Role = null!, event: BattleTriggerEvent = BattleTriggerEvent.Casting, buffId: number, num: number) {
        if(!this.SkillModel.learned){
            return
        }
        var casting = this.SkillModel.casting;
        casting.skill = this;
        casting.caster = caster;
        casting.target = target;

        // 释放技能，施放条件在重写方法中自定义
        (casting as any)[event](buffId, num);
    }
    /** 播放角色技能释放的动画战报 */
    play(isr: ISkillReport, callback: Function) {
        var animator = this.SkillModel.animator;
        animator.isr = isr;
        animator.onComplete = callback;
        animator.casting();
    }

    /** 学习技能 */
    learn(role: Role) {
        var sm = this.SkillModel;
        if(role.RoleModel.table.id==312){
            console
        }
        if (!sm.learned && role.RoleModel.stage >= sm.table.open_stage) {
            sm.learned = 1;
            (sm.table.attrs as Array<any>).forEach(attr => {
                role.setNumericValue(attr.type, RoleModuleType.Skill, attr.value);
            });
        }
    }
    /**
   * 显示掉血特效
   * @param target 特效显示的目标角色身上
   */
    showEffectBlood(target: Role, effect: EffectDamage) {
        var parent = target?.RoleView?.node;
        if (!parent) {
            return
        }
        var pos = v3(0, 0);
        var path = "game/blood/normal";
        var isPlayFinishedRelease = true;
        switch (effect.hitEffect) {
            case BattleDamageType.Blood:
                path = "game/blood/blood";
                break;
            case BattleDamageType.Normal:
                path = "game/blood/normal";
                break;
            case BattleDamageType.Poison:
                path = "game/blood/poison";
                break;
            case BattleDamageType.Fire:
                path = "game/blood/fire";
                break;
            case BattleDamageType.Critical:
                path = "game/blood/critical";
                break;
            case BattleDamageType.Block:
                path = "game/blood/block";
                break;
            default:
                break;
        }
        var node = EffectSingleCase.instance.show(path, parent, { pos, isPlayFinishedRelease });
        var lab: Label = node.getChildByName("Layout")?.getChildByName("lab_num")?.getComponent(Label)!;
        lab.string = String(effect.value);
        target?.RoleView?.getComponent(RoleViewComp)?.setHpBar();
    }

    /**
  * 显示技能受击特效
  * @param target 特效显示的目标角色身上
  */
    showEffectHit(target: Role, path: string) {
        target?.RoleView?.loadEffectData(path)
    }
      /**
     * 显示回血施放特效
     * @param target 特效显示的目标角色上
     */
      showEffectRecovery(target: Role) {
        if(target?.RoleView?.node){
            var node = ViewUtil.createPrefabNode("game/role/recovery");
            node.addComponent(SpineFinishedRelease);
            node.parent = target.RoleView.node;
        }
    }


    /**
    * 显示加血数字
    * @param target 特效显示的目标角色身上
    */
    showRecoveryNum(target: Role, effect: EffectRecovery) {
        if (!effect.value) {
            return
        }
        var parent = target?.RoleView?.node;
        if (!parent) {
            return
        }

        var path = "game/blood/recovery";
        var pos = v3(0, 100);
        var isPlayFinishedRelease = true;
        var node = EffectSingleCase.instance.show(path, parent, { pos, isPlayFinishedRelease });
        var lab: Label = node.getChildByName("Layout")?.getChildByName("lab_num")?.getComponent(Label)!;
        lab.string = String(effect.value);
        target?.RoleView?.getComponent(RoleViewComp)?.setHpBar();
    }
}

export class EcsSkillSystem extends ecs.System {
    constructor() {
        super();
    }
}
